From 57daa6655da8c710e9b75b3286bcdb654d38e9d4 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Wed, 30 Nov 2005 19:26:32 +0000 Subject: [PATCH] Move the relocate.setupRelocation code into XendDomain, removing the mutual dependency between those two classes. Split the XendDomain constructor into two pieces so that XendDomainInfo can call XendDomain.instance even during the initial startup of XendDomain. These two together mean that there is no need for the horrendous hack using XendRoot.get_component to pass the singleton instance of XendDomain around. Both XendRoot.get_component and XendRoot.add_component can go. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomain.py | 25 ++++++++++------ tools/python/xen/xend/XendDomainInfo.py | 20 ++++++------- tools/python/xen/xend/XendRoot.py | 36 ------------------------ tools/python/xen/xend/server/relocate.py | 25 ++++------------ 4 files changed, 30 insertions(+), 76 deletions(-) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 4e76acfdbe..650a500e8f 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -24,6 +24,7 @@ import logging import os +import socket import sys import threading @@ -35,7 +36,6 @@ from xen.xend import XendRoot from xen.xend import XendCheckpoint from xen.xend.XendError import XendError from xen.xend.XendLogging import log -from xen.xend.server import relocate from xen.xend.xenstore.xswatch import xswatch @@ -54,15 +54,16 @@ class XendDomain: ## public: def __init__(self): - # Hack alert. Python does not support mutual imports, but XendDomainInfo - # needs access to the XendDomain instance to look up domains. Attempting - # to import XendDomain from XendDomainInfo causes unbounded recursion. - # So we stuff the XendDomain instance (self) into xroot's components. - xroot.add_component("xen.xend.XendDomain", self) - self.domains = {} self.domains_lock = threading.RLock() + + # This must be called only the once, by instance() below. It is separate + # from the constructor because XendDomainInfo calls back into this class + # in order to check the uniqueness of domain names. This means that + # instance() must be able to return a valid instance of this class even + # during this initialisation. + def init(self): self.domains_lock.acquire() try: self._add_domain( @@ -389,10 +390,15 @@ class XendDomain: dominfo = self.domain_lookup(domid) port = xroot.get_xend_relocation_port() - sock = relocate.setupRelocation(dst, port) + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((dst, port)) + except socket.error, err: + raise XendError("can't connect: %s" % err[1]) + sock.send("receive\n") XendCheckpoint.save(sock.fileno(), dominfo, live) - + def domain_save(self, domid, dst): """Start saving a domain to file. @@ -527,4 +533,5 @@ def instance(): inst except: inst = XendDomain() + inst.init() return inst diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index bbc7287f82..8f01f0aef0 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -33,14 +33,14 @@ import xen.lowlevel.xc from xen.util import asserts from xen.util.blkif import blkdev_uname_to_file -from xen.xend import image -from xen.xend import sxp -from xen.xend import XendRoot +import image +import sxp +import uuid +import XendDomain +import XendRoot + from xen.xend.XendBootloader import bootloader from xen.xend.XendError import XendError, VmError -from xen.xend.XendRoot import get_component - -import uuid from xen.xend.xenstore.xstransact import xstransact from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain @@ -338,9 +338,8 @@ def parseConfig(config): def domain_by_name(name): - # See comment in XendDomain constructor. - xd = get_component('xen.xend.XendDomain') - return xd.domain_lookup_by_name_nr(name) + return XendDomain.instance().domain_lookup_by_name_nr(name) + def shutdown_reason(code): """Get a shutdown reason from a code. @@ -1343,8 +1342,7 @@ class XendDomainInfo: new_dom = None try: - xd = get_component('xen.xend.XendDomain') - new_dom = xd.domain_create(config) + new_dom = XendDomain.instance().domain_create(config) new_dom.unpause() new_dom.removeVm(RESTART_IN_PROGRESS) except: diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index 29398df901..d94f63a58d 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -93,24 +93,6 @@ class XendRoot: self.configure() - def add_component(self, name, val): - """Add a xend component. - - @param name: component name - @param val: component object - """ - self.components[name] = val - - def get_component(self, name): - """Get a xend component from its name. - This is used as a work-round for problems caused by mutually - recursive imports. - - @param name: component name - @return: component object (or None) - """ - return self.components.get(name) - def _logError(self, fmt, *args): """Logging function to log to stderr. We use this for XendRoot log messages because they may be logged before the logger has been @@ -277,21 +259,3 @@ def instance(): except: inst = XendRoot() return inst - -def add_component(name, val): - """Register a component with XendRoot. - This is used to work-round import cycles. - - @param name: component name - @param val: component value (often a module) - """ - return instance().add_component(name, val) - -def get_component(name): - """Get a component. - This is used to work-round import cycles. - - @param name: component name - @return component or None - """ - return instance().get_component(name) diff --git a/tools/python/xen/xend/server/relocate.py b/tools/python/xen/xend/server/relocate.py index f7cda14ec9..c179eaf6f7 100644 --- a/tools/python/xen/xend/server/relocate.py +++ b/tools/python/xen/xend/server/relocate.py @@ -23,16 +23,12 @@ import StringIO from xen.web import protocol, tcp, unix from xen.xend import sxp -from xen.xend.XendError import XendError +from xen.xend import XendDomain from xen.xend import XendRoot +from xen.xend.XendError import XendError from xen.xend.XendLogging import log -xroot = XendRoot.instance() - - -DEBUG = 0 - class RelocationProtocol(protocol.Protocol): """Asynchronous handler for a connected relocation socket. """ @@ -111,8 +107,8 @@ class RelocationProtocol(protocol.Protocol): if self.transport: self.send_reply(["ready", name]) self.transport.sock.setblocking(1) - xd = xroot.get_component("xen.xend.XendDomain") - xd.domain_restore_fd(self.transport.sock.fileno()) + XendDomain.instance().domain_restore_fd( + self.transport.sock.fileno()) self.transport.sock.setblocking(0) else: log.error(name + ": no transport") @@ -120,6 +116,7 @@ class RelocationProtocol(protocol.Protocol): def listenRelocation(): + xroot = XendRoot.instance() if xroot.get_xend_unix_server(): path = '/var/lib/xend/relocation-socket' unix.listenUNIX(path, RelocationProtocol) @@ -128,15 +125,3 @@ def listenRelocation(): interface = xroot.get_xend_relocation_address() l = tcp.listenTCP(port, RelocationProtocol, interface=interface) l.setCloExec() - -def setupRelocation(dst, port): - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect((dst, port)) - except socket.error, err: - raise XendError("can't connect: %s" % err[1]) - - sock.send("receive\n") - print sock.recv(80) - - return sock -- 2.30.2